package com.atan.xiaohongshu.auth.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.atan.framework.common.exception.BizException;
import com.atan.xiaohongshu.auth.constant.BizDictConstants;
import com.atan.xiaohongshu.auth.constant.RedisConstants;
import com.atan.xiaohongshu.auth.enums.ResponseCodeEnum;
import com.atan.xiaohongshu.auth.model.vo.verificationcode.SendVerificationCodeReqVO;
import com.atan.xiaohongshu.auth.service.VerificationCodeService;
import com.atan.xiaohongshu.auth.sms.AliyunSmsSendHelper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@Service
@Slf4j
public class VerificationCodeServiceImpl implements VerificationCodeService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource(name = "taskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;


    @Autowired
    private AliyunSmsSendHelper aliyunSmsSendHelper;

    /**
     * 发送验证码
     *
     * @param sendVerificationCodeReqVO
     */
    @Override
    public void sendVerificationCode(SendVerificationCodeReqVO sendVerificationCodeReqVO) throws InterruptedException {
        //获取手机号
        String phone = sendVerificationCodeReqVO.getPhone();

        //构建手机号RedisKey
        String verificationCodeKey = RedisConstants.getVerificationCodeKey(phone);
        //判断是否发送过验证码
        if (redisTemplate.hasKey(verificationCodeKey)) {
            //发送过验证码，提示频繁
            throw new BizException(ResponseCodeEnum.VERIFICATION_CODE_SEND_FREQUENTLY);
        }
        //提供6位数验证码
        String verificationCode = RandomUtil.randomNumbers(BizDictConstants.DEFAULT_VERIFICATION_CODE_LENGTH);

        // todo: 调用第三方短信发送服务
        // 使用 CountDownLatch 来等待异步任务完成
        CountDownLatch latch = new CountDownLatch(1);
        AtomicBoolean success = new AtomicBoolean(false);

        // 调用第三方短信发送服务
        threadPoolTaskExecutor.submit(() -> {
            String signName = "阿里云短信测试";
            String templateCode = "SMS_154950909";
            String templateParam = String.format("{\"code\":\"%s\"}", verificationCode);
            try {
                boolean result = aliyunSmsSendHelper.sendSmsMessage(phone, signName, templateCode, templateParam);
                success.set(result);
            } catch (Exception e) {
                log.error("==> 短信发送错误: ", e);
            } finally {
                latch.countDown();
            }
        });
        // 等待异步任务完成
        latch.await();
        if (success.get()) {
            log.info("==> 手机号: {}, 已发送验证码：【{}】", phone, verificationCode);
            // 存储验证码到 redis, 并设置过期时间为 3 分钟
            redisTemplate.opsForValue().set(verificationCodeKey, verificationCode, BizDictConstants.DEFAULT_VERIFICATION_CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
        } else {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR);
        }
    }
}
